package service

import (
	"errors"
	"gin-bms/global"
	"gin-bms/model"
	"strconv"

	"gorm.io/gorm"
)

//添加基础路由
func CreateMenu(info model.SysMenu) (err error) {
	if !errors.Is(global.GLOBAL_DB.Where("name =?", info.Name).First(&model.SysMenu{}).Error, gorm.ErrRecordNotFound) {
		err = errors.New("存在重复name,请修改name")
		return err
	}
	err = global.GLOBAL_DB.Create(&info).Error
	return err
}

//删除基础路由
func DeleteMenu(id float64) (err error) {
	err = global.GLOBAL_DB.Preload("Parameters").Where("parent_id=?", id).First(&model.SysMenu{}).Error
	if err != nil {
		var menu model.SysMenu
		db := global.GLOBAL_DB.Preload("SysRoles").Where("id=?", id).First(&menu).Delete(&menu)
		err = global.GLOBAL_DB.Delete(&model.SysMenuParameter{}, "sys_menu_id=?", id).Error
		if len(menu.SysRoles) > 0 {
			err = global.GLOBAL_DB.Model(menu).Association("SysRoles").Delete(&menu.SysRoles)
		} else {
			err = db.Error
		}
	} else {
		errors.New("此菜单存在子菜单不可删除")
	}
	return err
}

//更新基础路由
func UpdateMenu(info model.SysMenu) (err error) {
	var oldMenu model.SysMenu
	newMenuMap := make(map[string]interface{})
	newMenuMap["keep_alive"] = info.KeepAlive
	//newMenuMap["default_menu"] = info.DefaultMenu
	newMenuMap["parent_id"] = info.ParentId
	newMenuMap["path"] = info.Path
	newMenuMap["name"] = info.Name
	newMenuMap["hidden"] = info.Hidden
	newMenuMap["component"] = info.Component
	newMenuMap["title"] = info.Title
	newMenuMap["icon"] = info.Icon
	newMenuMap["sort"] = info.Sort

	err = global.GLOBAL_DB.Transaction(func(tx *gorm.DB) error {
		db := tx.Where("id=?", info.ID).Find(&oldMenu)
		if oldMenu.Name != info.Name {
			if !errors.Is(tx.Where("id <> ? AND name = ?", info.ID, info.Name).First(&model.SysMenu{}).Error, gorm.ErrRecordNotFound) {
				global.GLOBAL_LOG.Debug("存在相同name修改失败")
				return errors.New("存在相同name修改失败")
			}
		}
		txErr := tx.Unscoped().Delete(&model.SysMenuParameter{}, "sys_menu_id = ?", info.ID).Error
		if txErr != nil {
			global.GLOBAL_LOG.Debug(txErr.Error())
			return txErr
		}
		if len(info.Parameters) > 0 {
			for k, _ := range info.Parameters {
				info.Parameters[k].SysMenuID = info.ID
			}
			txErr = tx.Create(&info.Parameters).Error
			if txErr != nil {
				global.GLOBAL_LOG.Debug(txErr.Error())
				return txErr
			}
		}

		txErr = db.Updates(newMenuMap).Error
		if txErr != nil {
			global.GLOBAL_LOG.Debug(txErr.Error())
			return txErr
		}
		return nil
	})
	return err
}

//获取一条基础路由
func GetMenu(id float64) (err error, menu model.SysMenu) {
	err = global.GLOBAL_DB.Preload("Parameters").Where("id=?", id).First(&menu).Error
	return
}

//获取当前角色树
func GetRoleMenus(roleId string) (err error, menus []model.SysRoleMenu) {
	err = global.GLOBAL_DB.Where("role_id = ?", roleId).Order("sort").Find(&menus).Error
	return err, menus
}

////获取基础路由树
//func GetSysMenuList() (err error, list interface{}, total int64) {
//	var menus []model.SysMenu
//	err, treeMap := getSysMenuTreeMap()
//	menus = treeMap["0"]
//	for i := 0; i < len(menus); i++ {
//		err = getSysMenuChildrenList(&menus[i], treeMap)
//	}
//	return err, menus, total
//}

//获取基础路由树
func GetMenuTree() (err error, menus []model.SysMenu) {
	err, treeMap := getMenuTreeMap()
	menus = treeMap["0"]
	for i := 0; i < len(menus); i++ {
		err = getMenuChildrenList(&menus[i], treeMap)
	}
	return err, menus
}

//私有：获取路由树
func getMenuTreeMap() (err error, treeMap map[string][]model.SysMenu) {
	var menus []model.SysMenu
	treeMap = make(map[string][]model.SysMenu)
	err = global.GLOBAL_DB.Order("sort").Preload("Parameters").Find(&menus).Error
	for _, v := range menus {
		treeMap[v.ParentId] = append(treeMap[v.ParentId], v)
	}
	return err, treeMap
}

//私有：获取路由子菜单
func getMenuChildrenList(menu *model.SysMenu, treeMap map[string][]model.SysMenu) (err error) {
	menu.Children = treeMap[strconv.Itoa(int(menu.ID))]
	for i := 0; i < len(menu.Children); i++ {
		err = getMenuChildrenList(&menu.Children[i], treeMap)
	}
	return err
}
